package caidan;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;

import caidan.data.FoodData;
import jinyilw.swing.FontTools;
import jinyilw.swing.graphics.GraphicsTools;
import jinyilw.swing.rlaf.ui.RScrollBarUI;
import jinyilw.swing.visuals.Rcomp.RButton;
import jinyilw.swing.visuals.Rcomp.RDialog;
import jinyilw.swing.visuals.panel.Position;

public class EditContentPanel extends Container
{
	private static final long serialVersionUID = -2048923677245744300L;
	private boolean[] isPositionChanges;
	private ArrayList<EditFoodPanel>[] foodPanelLists;
	final PositionConfiger positionConfiger = new PositionConfiger();
	final ContentContainer contentContainer = new ContentContainer();
	final JScrollPane scrollPane = contentContainer.getScrollPane();
	final Container glassPane = new GlassPanel();
	private Position[][] choosePositions;
	JLabel[] categoryLabels;
	private RButton save, cancel, clear;
	private OneMealPanel currentMeal;
	private int maxCol = 0, contentMaxRow = 0;
	private int chooseRow = 1;
	private float minStartRow = 2.5f;
	private int[] categoryCols, startCols;
	private RDialog dialog;
	private int[] chooseNums;

	public EditContentPanel(ArrayList<FoodData>[] foodDataLists,
			int[] categoryCols, int[] chooseNums, String[] categoryNames,
			RDialog dialog)
	{
		this.dialog = dialog;
		this.chooseNums = chooseNums;
		init(foodDataLists, categoryCols, categoryNames);
	}

	private void init(ArrayList<FoodData>[] foodDataLists, int[] categoryCols,
			String[] categoryNames)
	{
		this.categoryCols = categoryCols;
		startCols = new int[categoryCols.length];
		for (int i = 0; i < categoryCols.length; i++)
		{
			startCols[i] = maxCol;
			maxCol += categoryCols[i] + 1;
		}
		maxCol--;
		positionConfiger.setMaxColumn(maxCol);

		int chooseCol;
		double fChoose;
		choosePositions = new Position[foodDataLists.length][];
		isPositionChanges = new boolean[foodDataLists.length];
		foodPanelLists = new ArrayList[foodDataLists.length];
		for (int i = 0; i < foodPanelLists.length; i++)
		{
			foodPanelLists[i] = new ArrayList<EditFoodPanel>();
			choosePositions[i] = new Position[chooseNums[i]];

			fChoose = startCols[i]
					+ (categoryCols[i] - choosePositions[i].length) / 2.0;
			chooseCol = (int) fChoose;
			isPositionChanges[i] = fChoose > chooseCol;
			for (int j = 0; j < choosePositions[i].length; j++)
				choosePositions[i][j] = positionConfiger
						.createPosition(chooseRow, chooseCol++);
			int size = foodDataLists[i].size();
			for (int j = 0; j < size; j++)
				foodPanelLists[i].add(new EditFoodPanel(foodDataLists[i].get(j),
						choosePositions[i], j, this));

			setPositons(foodPanelLists[i], startCols[i], categoryCols[i]);
			int row = (int) Math
					.ceil(foodPanelLists[i].size() / (double) categoryCols[i]);
			if (row > contentMaxRow)
				contentMaxRow = row;
		}

		for (int i = 0; i < foodPanelLists.length; i++)
			for (EditFoodPanel foodPanel : foodPanelLists[i])
				contentContainer.add(foodPanel);

		add(glassPane);
		categoryLabels = new JLabel[categoryNames.length];
		Font font = FontTools.getLargeFont();
		for (int i = 0; i < categoryLabels.length; i++)
		{
			categoryLabels[i] = new JLabel(categoryNames[i]);
			categoryLabels[i].setFont(font);
			categoryLabels[i].setHorizontalAlignment(SwingConstants.CENTER);
			add(categoryLabels[i]);
		}
		save = new RButton("保存");
		cancel = new RButton("取消");
		clear = new RButton("清空");

		add(scrollPane);
		add(save);
		add(cancel);
		add(clear);
		save.setBackground(Color.green.brighter());
		cancel.setBackground(Color.red.brighter());
		clear.setBackground(Color.yellow.brighter());
		save.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				dialog.dispose();
				updateMeal();
			}
		});
		cancel.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				dialog.dispose();
			}
		});
		clear.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent e)
			{
				clearChooses();
			}
		});
	}

	private void setPositons(ArrayList<EditFoodPanel> foodPanels, int startCol,
			int categoryCol)
	{
		int size = foodPanels.size();
		for (int i = 0; i < size; i++)
		{
			foodPanels.get(i).setPosition(positionConfiger.createPosition(
					i / categoryCol, startCol + i % categoryCol));
		}
	}

	public void setCurrentMeal(OneMealPanel oneMeal)
	{
		currentMeal = oneMeal;
		clearChooses();
		int[][] data = oneMeal.getData();
		int index;
		for (int i = 0; i < data.length; i++)
		{
			for (int j = 0; j < data[i].length; j++)
			{
				index = data[i][j];
				if (index > -1 && index < foodPanelLists[i].size())
					foodPanelLists[i].get(index)
							.initChoose(choosePositions[i][j]);
			}
		}
		repaint();
	}

	@Override
	public void setBounds(int x, int y, int width, int height)
	{
		if ((getWidth() == width && getHeight() == height)
				|| positionConfiger == null)
		{
			super.setBounds(x, y, width, height);
			return;
		}
		updateSize(width, height);
		super.setBounds(x, y, width, height);
	}

	public void updateSize(int width, int height)
	{
		int xx = (width - 390) / 2, yy = height - 45;
		clear.setBounds(xx, yy, 50, 30);
		xx += 180;
		cancel.setBounds(xx, yy, 50, 30);
		xx += 180;
		save.setBounds(xx, yy, 50, 30);
		glassPane.setBounds(0, 0, width, height);
		int contentY = (int) ((positionConfiger.getH()
				+ positionConfiger.getS()) * minStartRow);
		int contentH = yy - 15 - contentY;
		scrollPane.setBounds(0, contentY, width, contentH);

		int chang = positionConfiger.getW() / 2;
		for (int i = 0; i < foodPanelLists.length; i++)
		{
			for (EditFoodPanel foodPanel : foodPanelLists[i])
				foodPanel.updatePosition();
			for (Position p : choosePositions[i])
			{
				p.update();
				if (isPositionChanges[i])
					p.change(chang, 0);
				if (p.isUsed())
					foodPanelLists[i].get((int) p.getData()).setBounds(p.getX(),
							p.getY(), p.getW(), p.getH());
			}
			int x = choosePositions[i][0].getX(),
					y = choosePositions[i][0].getY() - 25;
			int mi = choosePositions[i].length - 1;
			int w = choosePositions[i][mi].getX() - choosePositions[i][0].getX()
					+ positionConfiger.getW();
			categoryLabels[i].setBounds(x, y, w, 18);
		}
	}

	public void clearChooses()
	{
		for (int i = 0; i < foodPanelLists.length; i++)
			for (EditFoodPanel foodPanel : foodPanelLists[i])
				foodPanel.clear();
		repaint();
	}

	public void updateMeal()
	{
		int[][] data = currentMeal.getData();
		Position p;
		for (int i = 0; i < data.length; i++)
		{
			for (int j = 0; j < data[i].length; j++)
			{
				p = choosePositions[i][j];
				if (p.isUsed())
					data[i][j] = (Integer) p.getData();
				else
					data[i][j] = -1;
			}
		}
		currentMeal.updateMeal();
	}

	public int getMaxCol()
	{
		return maxCol;
	}

	public int getMaxRow()
	{
		return contentMaxRow;
	}

	public void addNew(int editListsID, FoodData... foodDatas)
	{
		if (editListsID == -1)
			return;
		int size = foodPanelLists[editListsID].size();
		for (int i = 0; i < foodDatas.length; i++)
		{
			EditFoodPanel editFoodPanel = new EditFoodPanel(foodDatas[i],
					choosePositions[editListsID], size, this);
			editFoodPanel.setPosition(positionConfiger.createPosition(
					size / categoryCols[editListsID],
					startCols[editListsID] + size % categoryCols[editListsID]));
			foodPanelLists[editListsID].add(editFoodPanel);
			contentContainer.add(editFoodPanel);
			size++;
		}
		int row = (int) (Math.ceil(size / (double) categoryCols[editListsID]));
		if (row > contentMaxRow)
		{
			contentMaxRow = row;
			dialog.defaultSize();
		}
	}

	public void delete(int editListsID, int index)
	{
		if (editListsID == -1)
			return;
		ArrayList<EditFoodPanel> panels = foodPanelLists[editListsID];
		int size = panels.size();
		for (int i = size - 2; i >= index; i--)
		{
			Position position = panels.get(i).getPosition();
			EditFoodPanel editFoodPanel = panels.get(i + 1);
			editFoodPanel.setPosition(position);
			editFoodPanel.setIndex(i);
		}
		contentContainer.remove(panels.get(index));
		panels.remove(index);
	}

	public int getPreferredWidth()
	{
		return positionConfiger.getPreferredWidth();
	}

	public int getPreferredHeight()
	{
		return (int) ((contentMaxRow + minStartRow)
				* (positionConfiger.getH() + positionConfiger.getS())
				+ positionConfiger.getUpB() + 70);
	}

	class ContentContainer extends Container
	{
		private static final long serialVersionUID = 8315556711145060960L;
		private JScrollPane scrollPane;
		private Dimension preferredSize = new Dimension();

		@Override
		public Dimension getPreferredSize()
		{
			if (positionConfiger != null)
			{
				preferredSize.width = positionConfiger.getPreferredWidth()
						- RScrollBarUI.barWidth;
				preferredSize.height = contentMaxRow
						* (positionConfiger.getH() + positionConfiger.getS())
						+ positionConfiger.getUpB();
				return preferredSize;
			}
			return super.getPreferredSize();
		}

		public JScrollPane getScrollPane()
		{
			if (scrollPane == null)
				scrollPane = new JScrollPane(this);
			return scrollPane;
		}
	}

	class GlassPanel extends JComponent
	{
		private static final long serialVersionUID = -8911144692478394430L;

		@Override
		protected void paintComponent(Graphics g)
		{
			if (choosePositions == null)
				return;
			Graphics2D g2d = (Graphics2D) g;
			Stroke oldStroke = g2d.getStroke();
			g2d.setStroke(GraphicsTools.getDottedStroke());
			g2d.setColor(Color.gray);
			for (Position[] ps : choosePositions)
			{
				for (Position p : ps)
					if (!p.isUsed())
						g2d.drawRoundRect(p.getX() + 2, p.getY() + 2,
								p.getW() - 6, p.getH() - 6, 8, 8);
			}
			g2d.setStroke(oldStroke);
		}
	}
}
